package service

import (
	"context"
	"errors"
	//"github.com/gin-gonic/gin"
	v1 "server_go/api/v1"
	"server_go/internal/model"
	"server_go/internal/repository"

	"golang.org/x/crypto/bcrypt"
	"gorm.io/gorm"
	"time"
)

type AdminService interface {
	Login(ctx context.Context, req v1.LoginRequest) (model.Admin, string, error)
	DeleteUser(ctx context.Context, userID uint) error
	GetUsers(ctx context.Context) (*[]v1.GetUsersResponse, error)
}

func NewAdminService(
	service *Service,
	adminRepository repository.AdminRepository,
) AdminService {
	return &adminService{
		Service:         service,
		adminRepository: adminRepository,
	}
}

type adminService struct {
	*Service
	adminRepository repository.AdminRepository
}

func (s *adminService) Login(ctx context.Context, req v1.LoginRequest) (model.Admin, string, error) {

	if req.Account == "" || req.Password == "" {
		return model.Admin{}, "", v1.ErrBadRequest
	}
	admin, err := s.adminRepository.GetAdminByAccount(ctx, req.Account)
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return model.Admin{}, "", v1.ErrAdminNotFound
		}
		return model.Admin{}, "", v1.ErrInternalServerError
	}
	if admin.Type != model.AdminType {
		return model.Admin{}, "", v1.ErrType
	}
	err = bcrypt.CompareHashAndPassword([]byte(admin.Password), []byte(req.Password))
	if err != nil {
		return model.Admin{}, "", v1.ErrPwd
	}
	token, _ := s.jwt.GenToken(admin.ID, time.Now().Add(time.Hour*24*7), model.AdminType, 0)
	return *admin, token, nil
}

func (s *adminService) DeleteUser(ctx context.Context, userId uint) error {
	err := s.tm.Transaction(ctx, func(ctx context.Context) error {
		_, err := s.adminRepository.GetUserByID(ctx, userId)
		if err != nil {
			return v1.ErrAdminNotFound
		}
		return nil
	})
	err = s.adminRepository.DeleteUser(ctx, userId)
	if err != nil {
		return err
	}
	return nil
}

// 查询所有用户
func (s *adminService) GetUsers(ctx context.Context) (*[]v1.GetUsersResponse, error) {
	users, err := s.adminRepository.GetUsers(ctx)

	if err != nil {
		return nil, err
	}
	var getUsersResponse []v1.GetUsersResponse
	for _, user := range users {
		getUsersResponse = append(getUsersResponse, v1.GetUsersResponse{
			ID:      user.ID,
			Account: user.Account,
			Name:    user.Name,
		})
	}
	return &getUsersResponse, nil
}
